﻿using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;

namespace GBricks
{
  public static class Disposable
  {
    static Disposable() {
      Empty = new EmptyDisposable();
    }

    public static IDisposable Empty { get; private set; }

    [Pure]
    public static IDisposable Create(Action dispose) {
      return dispose != null ? new ActionDisposable(dispose) : Empty;
    }

    public static bool DisposeWhenNotNull(this IDisposable disposable) {
      if(disposable != null) {
        disposable.Dispose();
        return true;
      }//if
      return false;
    }

    [DebuggerDisplay("<Action Disposable{ Action == null ? \" [Disposed]\" : System.String.Empty }>")]
    private sealed class ActionDisposable : IDisposable
    {
      public ActionDisposable(Action action) {
        Argument.NotNull(action, "action");
        Action = action;
      }

      private Action Action { get; set; }

      public void Dispose() {
        Contract.Ensures(Action == null);

        if(Action != null) {
          Action();
          Action = null;
        }//if
      }
    }

    [DebuggerDisplay("<Empty Disposable>")]
    private sealed class EmptyDisposable : IDisposable
    {
      void IDisposable.Dispose() { }
    }
  }
}
